/*
 * Class: DBMService
 * 
 * Used by the controller to interact with the database manager classes.
 * 
 * Version 1.0 Sonny Guenette - 2011-11-27
 * 		Initial implementation
 * 
 * Version 1.1 M-A Lavoie - 2011-12-04
 * 		Changed events list from HashSet to List
 * 
 * Version 1.2 Sonny Guenette - 2011-12-09
 * 		Added new methods
 * 
 * Version 1.3 Sonny Guenette - 2011-12-11
 * 		Debugged the connection problem
 *
 * Copyright GPP - Genuine People Personality inc.
 * 
 */

package dbManager;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import calendarEventManager.CEMAgenda;
import calendarEventManager.CEMEvent;
import dbManager.DBMAgenda;
import dbManager.DBMTable;
import dbManager.DBConnection;

public class DBMService {
	private static DBMService m_oInstance = null;

	DBMAgenda m_oAgenda;
	DBMTable m_oTable;
	DBMEvent m_oEvent;
	DBConnection m_oDB;
	Connection m_oCon;
	
	Statement m_oStmt;

	//***********************************************************
	// Method: getInstance
	// Description: This method make sure that there is only one
	//              instance of CEMCalendar and respects the
	//              Singleton design pattern.
	//**********************************************************
	/**
	 * @param
	 */
	public synchronized static DBMService getInstance(){
		if(m_oInstance == null){
			m_oInstance = new DBMService();
		}
		return m_oInstance;
	}
	
	//*****************************************************
	// Method: DBMService
	// Description: Class constructor
	//*****************************************************
	/**
	 * @param
	 */
	private DBMService(){
		m_oAgenda = new DBMAgenda();
		m_oTable = new DBMTable();
		m_oEvent = new DBMEvent();
		m_oDB = new DBConnection();
		m_oCon = null;
	}

	//****************************************************************************
	// Method: initializeDataBase
	// Description: Make the connection to the database and add the tables we need
	//****************************************************************************
	/**
	 * @param
	 * 
	 * @throws SQLException 
	 */
	public void initializeDataBase(){
		m_oDB.connectDB();
		
		m_oCon = m_oDB.getDBCon();

		m_oTable.createTable(m_oCon);
	}
	
	//****************************************************************************
	// Method: TESTinitializeDataBase
	// Description: Make the connection to the database and add the tables we need.
	//
	//				USED BY THE TEST ONLY
	//****************************************************************************
	/**
	 * @param
	 * 
	 * @throws SQLException 
	 */
	public void TESTinitializeDataBase() throws SQLException{
		m_oDB.connectDB();
		
		m_oCon = m_oDB.getDBCon();
		
		resetDataBase(m_oCon);

		m_oTable.createTable(m_oCon);
	}
	
	//***************************************************
	// Method: resetDatabase
	// Description: Drop all tables in the dataBase. Used for tests.
	//***************************************************
	/**
	 * @param p_oCon The connection object
	 */
	private void resetDataBase(Connection p_oCon) throws SQLException{
		m_oStmt = p_oCon.createStatement();
		m_oStmt.executeUpdate("DROP TABLE IF EXISTS agendas");
		m_oStmt.executeUpdate("DROP TABLE IF EXISTS events");
	}

	//*********************************************************
	// Method: disconnect
	// Description: Close the connection to the database
	//*********************************************************
	/**
	 * @param
	 */
	public void disconnect(){
		m_oDB.disconnectDB();
	}

	//**************************************************************
	// Method: createAgenda
	// Description: Add a new agenda in the database
	//**************************************************************
	/**
	 * @param p_oNewAgenda The agenda object that contain all the informations needed
	 * 
	 * @return true if the agenda is successfully added
	 */
	public boolean createAgenda(CEMAgenda p_oNewAgenda){
		return m_oAgenda.createAgenda(p_oNewAgenda, m_oCon);
	}
	
	//**************************************************************
	// Method: nameAlreadyExist
	// Description: Check if there is already an agenda with this name in the database
	//**************************************************************
	/**
	 * @param p_sAgendaName The agenda name
	 * 
	 * @return true if there is already an agenda with this name
	 */
	public boolean nameAlreadyExist(String p_sAgendaName){
		return m_oAgenda.nameAlreadyExist(p_sAgendaName, m_oCon);
	}

	 //******************************************************
	 // Method: updateAgenda
	 // Description: Change the informations for an agenda 
	 //***************************************************** 
	 /**
	 * @param p_oNewAgenda The agenda object that contain all the informations needed
	 * 
	 * @return true if the agenda is successfully modified
	 */
	public boolean updateAgenda(CEMAgenda p_oNewAgenda){
		return m_oAgenda.updateAgenda(p_oNewAgenda, m_oCon);
	}

	 //******************************************************
	 // Method: deleteAgenda
	 // Description: Delete an agenda from the database 
	 //***************************************************** 
	 /**
	 * @param p_nAgendaId The agenda Id
	 * 
	 * @return true if the agenda is successfully deleted
	 */
	public boolean deleteAgenda(int p_nAgendaId){
		return m_oAgenda.deleteAgenda(p_nAgendaId, m_oCon);
	}

	 //******************************************************
	 // Method: getAgendaId
	 // Description: Retrieve the Id of an agenda
	 //***************************************************** 
	 /**
	 * @param p_oNewAgenda The agenda object that contain all the informations needed
	 * 
	 * @return the agenda id or -1 if there's an error
	 */
	public int getAgendaId(CEMAgenda p_oNewAgenda){
		return m_oAgenda.getAgendaId(p_oNewAgenda, m_oCon);
	}

	 //******************************************************
	 // Method: selectAllTupleAgenda
	 // Description: Select all agendas in the database
	 //***************************************************** 
	 /**
	 * @param p_oAgendaList The list that will contain all the agendas
	 * 
	 * @return true if the agendas are successfully retrieved
	 */
	public boolean selectAllTuple(List<CEMAgenda> p_oAgendaList){
		return m_oAgenda.selectAllTupleAgenda(m_oCon, p_oAgendaList);
	}

	//**************************************************************
	// Method: createEvent
	// Description: Add a new event in the database
	//**************************************************************
	/**
	 * @param p_oNewEvent The event to add
	 * 
	 * @return true if the event is successfully added
	 */
	public boolean createEvent(CEMEvent p_oNewEvent){
		return m_oEvent.createEvent(p_oNewEvent, m_oCon);
	}

	//**************************************************************
	// Method: checkConflictEvent
	// Description: Check if there is a schedule conflict before
	//				adding the new event.
	//**************************************************************
	/**
	 * @param p_oNewEvent The event to add
	 * 
	 * @return true if there is a conflict
	 */
	public boolean checkConflictEvent(CEMEvent p_oNewEvent){
		return m_oEvent.checkConflictEvent(p_oNewEvent, m_oCon);
	}

	//**************************************************************
	// Method: updateEvent
	// Description: Modify an event
	//**************************************************************
	/**
	 * @param p_oNewEvent The new event
	 * 
	 * @return true if the event is successfully modified
	 */
	public boolean updateEvent(CEMEvent p_oNewEvent){
		return m_oEvent.updateEvent(p_oNewEvent, m_oCon);
	}

	//**************************************************************
	// Method: deleteEvent
	// Description: delete an event
	//**************************************************************
	/**
	 * @param p_nEventId The event id
	 * 
	 * @return true if the event is successfully deleted
	 */
	public boolean deleteEvent(int p_nEventId){
		return m_oEvent.deleteEvent(p_nEventId, m_oCon);
	}

	//**************************************************************
	// Method: selectAllTupleEvent
	// Description: select all the event for an agenda
	//**************************************************************
	/**
	 * @param p_oEventsList The list that contain all the events
	 * @param p_nAgendaId The agenda id from which to retrieve the events
	 * 
	 * @return true if the events are successfully retrieved
	 */
	public boolean selectAllTupleEvent(List<CEMEvent> p_oEventsList, int p_nAgendaId){
		return m_oEvent.selectAllTupleEvent(m_oCon, p_oEventsList, p_nAgendaId);
	}

	//**************************************************************
	// Method: getEventId
	// Description: Retrieve the id for an event
	//**************************************************************
	/**
	 * @param p_oNewEvent The event from which we want the id
	 * 
	 * @return the event id or -1 if there is an error
	 */
	public int getEventId(CEMEvent p_oNewEvent){
		return m_oEvent.getEventId(p_oNewEvent, m_oCon);
	}
}